package main

import "fmt"

//自定义类型  类型别名
type myint int
type yourint = int

//结构体
type person struct {
	name    string
	age     int
	lixiang []string
}

func f1(x *person) {
	// (*x).age = 999
	x.age = 999
}

//构造函数:约定以new开头的
//返回的是结构体还是结构体指针
//当结构体里面的字段少时可以返回结构体 多时返回结构体指针 减少内存开销
func newf2(name string, age int, lixinag []string) *person {
	return &person{
		name:    name,
		age:     age,
		lixiang: lixinag,
	}
}

func main() {
	fmt.Println("自定义类型  类型别名 ")
	var n myint
	n = 100
	fmt.Println(n)
	fmt.Printf("%T\n", n)

	var m yourint
	m = 100
	fmt.Println(m)
	fmt.Printf("%T\n", m)

	var c rune
	c = '种'
	fmt.Println(c)
	fmt.Printf("%T\n", c)

	fmt.Println(`表示main包下定义的NewInt类型。b的类型是int。
	MyInt类型只会在代码中存在，编译完成时并不会有MyInt类型。`)
	fmt.Println(`Go语言中没有“类”的概念，也不支持“类”的继承等面向对象的概念。
	Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。`)
	fmt.Println(`Go语言中通过struct来实现面向对象。`)
	var j1 person
	j1.name = "wjp"
	j1.age = 1
	j1.lixiang = []string{"xiza", "shuijai"}

	fmt.Println(j1)
	fmt.Printf("%T\n", j1)
	//匿名结构体,用于临时使用
	// var j2 struct {
	// 	name    string
	// 	age     int
	// 	lixiang []string
	// }

	// j2.name = "匿名结构体"
	// j2.age = 12
	// j2.lixiang = []string{"匿名结构体", "new int string bool返回指针 make slice map channel返回原类型"}
	j22 := person{
		name:    "匿名结构体",
		age:     12,
		lixiang: []string{"匿名结构体", "new int string bool返回指针 make slice map channel返回原类型"},
	}
	fmt.Println(j22)
	fmt.Printf("%T\n", j22)
	//结构体是值类型
	//函数传参永远是拷贝副本
	f1(&j1)
	fmt.Println(j1)
	var j3 = new(person) //获取结构体指针1
	j3.age = 89
	fmt.Printf("%T\n", j3)
	fmt.Printf("%p\n", j3)
	fmt.Printf("%x\n", &j3)
	fmt.Printf("%v\n", j3)
	// 结构体指针2
	var j4 = person{ //获取结构体指针2  +&
		name: "jiegouti2",
		age:  12,
	}
	fmt.Println(j4)
	j5 := person{ //获取结构体指针3  +&
		"jiegouti3",
		13,
		[]string{"13"},
	}
	fmt.Println(j5)
	//结构体内存地址是连续的  切片16
	var j6 struct {
		a int8 //8bit =》1byte
		b int8
		c int8
	}
	j6.a = 10
	j6.a = 11
	j6.a = 12
	fmt.Printf("%p\n", &(j6.a))
	fmt.Printf("%p\n", &(j6.b))
	fmt.Printf("%p\n", &(j6.c))
	//面向接口编程

}
